#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <math.h>
#include "rngs.h"
#include "dominion.h"
#include "dominion_helpers.h"
#include "unittests.h"
#include "interface.h"

#define MAX_ITER 100000

int get_random_coin() {
    int coins[] = {copper, silver, gold};
    int coin = floor(rand() % 2);
    return coins[coin];
}

int randomize_deck(int player, struct gameState *state, int *card_list, int deckSize) {
    int randomCard;
    int card;
    int shouldBeCoin;
    int cardListSize = sizeof(card_list);
    state->deckCount[player] = 0;
    // Build up a random deck of cards of size deckSize
    for (int deckIndex = 0; deckIndex < deckSize; deckIndex++) {
        // Get a random card from the card_list or a coin card
        // ~30% chance of making the card a coin
        shouldBeCoin = (rand() % 100) < 30 ? 1 : 0;

        if (shouldBeCoin == 1) {
            randomCard = get_random_coin();
        } else {
            card = floor(rand() % cardListSize);
            randomCard = card_list[card];
        }
        // Put the card into our deck and increment our deckCount
        state->deck[player][deckIndex] = randomCard;
        state->deckCount[player]++;
    }
    return 0;
}

int main(int argc, char **argv) {
    int player1 = 0;
    int seed = time(NULL);
    srand(seed);

    struct gameState state;
    int kingdom_cards[10] = {adventurer, council_room, feast, gardens, mine,
        remodel, smithy, village, baron, great_hall};

    printf("Random Testing adventurer_effect()\n");
    for (int i = 0; i < MAX_ITER; ++i) {
        memset(&state, 0, sizeof(struct gameState)); // clear the game state
        initializeGame(2, kingdom_cards, seed, &state); // initialize a new game
        // Random deck size between 0 and 20
        int deckSize;
        if ((rand() % 100) > 75) {
            deckSize = 0;
        } else {
            deckSize = rand() % 20;
        }

        int skew = rand() % 100; // Do some things more often then others
        if (skew > 70) {
            // No coins, just kingdom cards
            memcpy(state.deck[player1], kingdom_cards, 10);
            state.deckCount[player1] = 10;
        } else if (skew > 30) {
            // No coins, just kingdom cards
            // Only coins
            for (int k = 0; k < deckSize; ++k) {
                state.deck[player1][k] = get_random_coin();
            }
            state.deckCount[player1] = deckSize;
        } else {
            // Some coins, some cards
            randomize_deck(player1, &state, (int*)kingdom_cards, deckSize);
        }
        if ((rand() % 100) > 50) {
            state.deck[player1][0] = gold;
        }
        // Test adventurer with this randomized state
        adventurer_effect(player1, &state);
        // Commented out the assertions because the card doesn't always succeed
        // if there aren't enough treasure cards in the deck.

        /*
        int handCount = state.handCount[player1] - 1;
        for (int i = 0; i <= 1; ++i) {
        handCount -= i;
        assert(state.hand[player1][handCount] == copper ||
            state.hand[player1][handCount] == silver ||
            state.hand[player1][handCount] == gold);
        }
        */
    }

    return 0;
}